package com.apache.client.protocol;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

import com.apache.api.vo.ResultEntity;
import com.apache.exception.BusinessException;
import com.apache.uct.common.ToolsUtil;

public abstract class AbstractProtocolClient {

	public abstract ResultEntity doService(String beanId, String methodKey, Map<String, Object> params);

	protected String buildXml(String beanId, String methodKey, String respType, Map<String, Object> params) {
		try {
			Element root = builderHeaderInfo(methodKey, beanId, respType, "false");

			Element body = new Element("Body"); // 生成元素：Body

			addElementToBody(body, params);
			root.addContent(body);
			return elementToString(root);

		} catch (Exception e) {

		}
		return "";
	}

	protected ResultEntity getResultEntity(String message) {
		ResultEntity resultEntity = new ResultEntity();
		resultEntity.setResult("false");
		resultEntity.setMessage(message);
		return resultEntity;
	}

	private Element builderHeaderInfo(String methodCode, String beanId, String paramtype, String isClose) {
		Element root, head;
		Element hVersion, hPCode, hParamType, hBeanId, hSocketCLose;

		root = new Element("xml-body"); // 生成根元素：Root
		head = new Element("Head"); // 生成元素：Head

		hVersion = new Element("Version");
		hPCode = new Element("MethodCode");
		hBeanId = new Element("BeanId");
		hParamType = new Element("ParamType");
		hSocketCLose = new Element("SocketClose");

		hVersion.setText("1.0");
		hPCode.setText(methodCode);
		hBeanId.setText(beanId);
		hParamType.setText(paramtype);
		hSocketCLose.setText(isClose);

		head.addContent(hVersion);
		head.addContent(hPCode);
		head.addContent(hBeanId);
		head.addContent(hParamType);
		head.addContent(hSocketCLose);
		root.addContent(head);
		return root;
	}

	private String elementToString(Element root) throws BusinessException, FileNotFoundException, IOException {
		Document doc = new Document(root);
		String xmlfilename;
		Format format = Format.getRawFormat();
		format.setEncoding("UTF-8"); // 设置xml文件的字符为gb2312
		format.setIndent("    "); // 设置xml文件的缩进为4个空格
		XMLOutputter XMLOut = new XMLOutputter(format);// 元素后换行一层元素缩四格
		xmlfilename = XMLOut.outputString(doc);
		return xmlfilename;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private void addElementToBody(Element eBody, Map<String, Object> tranMap) throws Exception {
		Element element_tmp;
		for (String key : tranMap.keySet()) {
			if (ToolsUtil.isNotNull(key)) {
				element_tmp = new Element(key);
				String keyValueClass = tranMap.get(key).getClass().getSimpleName();
				if ("ArrayList".equals(keyValueClass) || "List".equals(keyValueClass)) {
					String valueClass = ((List) tranMap.get(key)).get(0).getClass().getSimpleName();
					if ("String".equals(valueClass)) {
						addElementsToBodyList(element_tmp, (List) tranMap.get(key));
					} else {
						addElementsToBody(element_tmp, (List) tranMap.get(key));
					}
				} else if ("Map".equalsIgnoreCase(keyValueClass) || "HashMap".equalsIgnoreCase(keyValueClass)) {
					addElementsToBodyMap(element_tmp, (Map) tranMap.get(key));
				} else {
					String keyValue = String.valueOf(tranMap.get(key));
					element_tmp.setText(keyValue);
				}
				eBody.addContent(element_tmp);
			}
		}
	}

	private void addElementsToBodyMap(Element eBody, Map<String, List<String>> tranList) {
		if (!ToolsUtil.isEmpty(tranList)) {
			for (String key : tranList.keySet()) {
				Element element_tmp;
				Element map_tmp = new Element("list");
				List<String> tranMap = tranList.get(key);
				for (String keyStr : tranMap) {
					if (ToolsUtil.isNotNull(key)) {
						element_tmp = new Element("String");
						element_tmp.setText(keyStr);
						map_tmp.addContent(element_tmp);
					}
				}
				eBody.addContent(map_tmp);
			}
		}
	}

	private void addElementsToBody(Element eBody, List<Map<String, Object>> tranList) {
		if (!ToolsUtil.isEmpty(tranList)) {
			int count = tranList.size();
			for (int i = 0; i < count; i++) {
				Element element_tmp;
				Element map_tmp = new Element("map");
				Map<String, Object> tranMap = tranList.get(i);
				for (String key : tranMap.keySet()) {
					if (ToolsUtil.isNotNull(key)) {
						element_tmp = new Element(key);
						String keyValue = String.valueOf(tranMap.get(key));
						element_tmp.setText(keyValue);
						map_tmp.addContent(element_tmp);
					}
				}
				eBody.addContent(map_tmp);
			}
		}
	}

	private void addElementsToBodyList(Element eBody, List<String> tranList) {
		if (!ToolsUtil.isEmpty(tranList)) {
			Element map_tmp = new Element("list");
			for (String key : tranList) {
				if (ToolsUtil.isNotNull(key)) {
					Element element_tmps = new Element("String");
					element_tmps.setText(key);
					map_tmp.addContent(element_tmps);
				}
			}
			eBody.addContent(map_tmp);
		}
	}
}
